<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>电视直播</title>
	<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" /> 
	
	<!-- ZUI 标准版压缩后的 CSS 文件 -->
	<link rel="stylesheet" href="/css/zui.min.css">
	<link rel="stylesheet" href="/css/chosen.min.css">		
	<!-- custom css -->
	<link rel="stylesheet" type="text/css" href="/css/index.css">
</head>
<body>

<div class="container-fixed"> 

<!-- 电视直播 begin -->
<div class="row live-panel">
	<div class="col-md-6">
		<select data-placeholder="选择一个频道..." class="chosen-select form-control" data-compact_search="true" id="channel-select">
		  <!-- 频道列表 -->
		</select>
	</div>
	<div class="col-md-6">
		<div class="input-group">
		  <div class="input-control has-icon-left has-icon-right search-example" id="channel-searchbox">
		    <input id="inputSearchExample3" type="search" class="form-control search-input" placeholder="搜索">
    		<label for="inputSearchExample3" class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label>
		  </div>
		  <span class="input-group-btn">
		    <button class="btn btn-primary" type="button" data-loading-text="正在搜索..." id="live-search-btn">搜索</button>
		  </span>
		</div>
	</div>
</div>

<div class="row">
<div class="panel" id="search-rs-panel">
	<div class="panel-body">
		<div><h5>
			<span style="font-size: large;"> 🎬️ </span>
			<span class="live-title">CCTV</span>&emsp;
			<span class="epg hidden">
				<span class="label label-danger">正在播出</span>&emsp;
				<span class="live-program"></span>&emsp;
				<span class="label">下一个节目</span>&emsp;
				<span class="next-start"></span> ~ 
				<span class="next-stop"></span>&emsp;
				<span class="next-program"></span>
			</span>
		</h5></div>
	</div>
	<div class="panel-footer">
		<!-- 指定播放器容器 -->
		<div class="artplayer-app" style="aspect-ratio: 16/9;"></div>
	</div>
</div>
</div>
<!-- 电视直播 end -->	

<!-- 直播源搜索结果 -->
<div class="row" id="channel-search-result">
	
</div>
	
</div>	
	
</body>

<!-- ZUI Javascript 依赖 jQuery -->
<script type="text/javascript" src="/js/jquery.js"></script>
<!-- ZUI 标准版压缩后的 JavaScript 文件 -->
<script type="text/javascript" src="/js/zui.min.js"></script>
<script type="text/javascript" src="/js/chosen.min.js"></script>
<!-- 引入基础脚本 mui-player.min.js -->
<script type="text/javascript" src="/js/hls.min.js"></script>
<script type="text/javascript" src="/js/artplayer.js"></script>
<!-- Art-Template.js -->
<script type="text/javascript" src="/js/template-web.min.js"></script>

<!-- 频道列表 -->
<script id="channel-list-template" type="text/html">
{{each channelList channel idx}}
<option value="{{channel.channel}}">{{channel.channel}}</option>
{{/each}}
</script>

<!-- 直播源搜索结果 -->
<script id="channel-source-result-template" type="text/html">
<div class="panel">
	<div class="panel-body">
		<table class="table table-hover table-striped">
			<thead>
			    <tr>
			      <th>频道</th>
			      <th>直播源</th>
			      <th>操作</th>
			    </tr>
		    </thead>
		  	<tbody class="video-list">
			{{each sourceList source idx}}
				<tr>
				  <td>{{source.videoname}}</td>
				  <td>{{source.link}}</td>
				  <td>
					  <button type="button" class="btn btn-mini btn-success search-live-play" data-name="{{source.videoname}}" data-link="{{source.link}}">播放</button>
				  </td>
				</tr>
			{{/each}}
		  	</tbody>
		</table>	
	</div>
</div>
</script>

<!-- 自定义脚本 -->
<script>

// 全局-直播源列表
var Global_Channel_Map = {};

/** 搜索框初始化 */
$('#channel-searchbox').searchBox({
    escToClear: true, // 设置点击 ESC 键清空搜索框
    onSearchChange: function(searchKey, isEmpty) {
        //console.log('搜索框文本变更：', searchKey);
    }
});
var channelSearchBox = $('#channel-searchbox').data('zui.searchBox');

$(function(){
	
// 播放
art.switchUrl('http://39.134.65.142/PLTV/88888888/224/3221225672/index.m3u8');

// 请求直播列表
/**
$.ajax({
	type: "GET",
    url: "/live/channel",
    dataType: "json",
    success: function(data){
		
		data.forEach(function(row, idx, arr){
			Global_Channel_Map[row.channel] = row.sourceList;
			if(idx == 0){
				addQuality(row.sourceList);
				art.switchUrl(row.sourceList[0].url);
				var channel = row.sourceList[0].channel
				// 搜索框
				channelSearchBox.setSearch(channel);
				// 播放器标题
				$('.live-title').html(channel);
				// 节目表
				getEpg(channel);
			}
		});
		
      	let result = template('channel-list-template',{'channelList' : data});  //===注意点:  模板上得rows要跟template上得rows对应
        $('#channel-select').html(result) //===直接赋值就可以实现了

		$('select.chosen-select').chosen({
		    no_results_text: '没有找到',    // 当检索时没有找到匹配项时显示的提示文本
		    search_contains: true,         // 从任意位置开始检索
		    compact_search: true 
		});
    },
    error: function(err){
		 art.notice.show = '系统发生错误，请稍后再访问！';
	}
});	
*/
	
});	


/** 节目表 */
function getEpg(channel){
$.ajax({
	type: "GET",
    url: "/live/epg?channel=" + channel,
    dataType: "json",
    success: function(data){
		
		data.forEach(function(row, idx, arr){
			
			var current = row.current;
			if(current){
				var content = row.content;
				$('.live-program').html(content);
				
				var next_start = data[idx + 1].start;
				var next_stop = data[idx + 1].stop;
				var next_content = data[idx + 1].content;
				
				$('.next-start').html(next_start);
				$('.next-stop').html(next_stop);
				$('.next-program').html(next_content);
				
				// 显示节目表
				$('.epg').removeClass("hidden");
				
				return;
			}
		});
    },
    error: function(err){
		 new $.zui.Messager('电视节目表加载出错啦，请稍后再试', {
		        type: 'danger' // 定义消息图标
		    }).show();
	}
});		
}


/** 选择框变化事件 **/
$('select.chosen-select').on('change', function(){
    // 用户改变了选择，快快处理
    console.log('用户选择了' + $(this).val());
    let channel = $(this).val();
    // 搜索框
	channelSearchBox.setSearch(channel);
	// 播放器标题
	$('.live-title').html(channel);
	// 节目表
	getEpg(channel);
    // 更新播放源列表
    addQuality(Global_Channel_Map[channel]);
    // 播放
    art.switchUrl(Global_Channel_Map[channel][0].url);
    
    
});


/** 搜索按钮触发 */	
$('#live-search-btn').on('click',function(){
	
	$('#live-search-btn').button('loading');
	
	var channel = channelSearchBox.getSearch();
	
	console.log('正在搜索频道：' + channel);
	
	$.ajax({
	    type:"GET",
	    url:"https://api.pearktrue.cn/api/tv/search.php?name=" + channel,
	    dataType:"json",
	    async: true,
	    timeout : 120*1000,
	    success:function (res) {
			if(res.code == 200){
				
				// 数据结果处理
				var resuleList = [];
				res.data.forEach(function(value,index){
					if(value.link.startsWith("http")){
						value.videoname = channel + "*";
						resuleList.push(value);
					}
				});
				
				let result = template('channel-source-result-template',{'sourceList' : resuleList});  //===注意点:  模板上得rows要跟template上得rows对应
           		$('#channel-search-result').html(result) //===直接赋值就可以实现了
			}
	    },
	    error: function(err){
		 	console.error(err);
		 	new $.zui.Messager('服务器开小差啦，请稍后再试', {
				type: 'danger',
		        icon: 'warning-sign' // 定义消息图标
		    }).show();
		},
		complete:function(xhr,status){
			console.log('请求结束：', status);
			//2.请求完成之后执行，最后执行，关闭loading一般在这里
			$('#live-search-btn').button('reset');
		},
	});
	
});

/** 搜索结果播放 */
$('#channel-search-result').on('click', '.search-live-play', function(){
	
	var name = $(this).attr('data-name');
	var link = $(this).attr('data-link');
	
	console.log('即将播放：' + name);
	
	// 播放器标题
	$('.live-title').html(name);
	// 更新播放源列表
    addTempQuality(link);
    // 播放
    art.switchUrl(link);
	
});

	
/** 播放器初始化 */
// 是否显示右键菜单
Artplayer.CONTEXTMENU = false;
// 自动重连次数
RECONNECT_TIME_MAX = 1;
// 通知显示事件（毫秒）
Artplayer.NOTICE_TIME = 5000;
const art = new Artplayer({
    container: '.artplayer-app',
    // url: 'https://live3.rxip.sc96655.com/live/CCTV-1H265_4000.m3u8',
    theme: '#ffad00', // 主题颜色
    type: 'm3u8',
    customType: {m3u8: playM3u8,},
    fullscreenWeb: true, // 网页全屏
    fullscreen: true, // 全屏
    hotkey: true, // 键盘控制播放
    //autoSize: true, // 播放器自动填充容器大小
    muted: true, // 自动播放必须先静音
    autoplay: true, // 是否自动播放
    pip: true, // 画中画
    isLive: true,
    airplay: true, // 投屏
    setting: true,
    // loop: true,
    flip: true,
    aspectRatio: true,
    quality: [],
    moreVideoAttr: {
        crossOrigin: 'anonymous',
    },
});

/** Support HLS **/
function playM3u8(video, url, art) {
    if (Hls.isSupported()) {
        if (art.hls) art.hls.destroy();
        const hls = new Hls();
        hls.loadSource(url);
        hls.attachMedia(video);
        art.hls = hls;
        art.on('destroy', () => hls.destroy());
        // 加载出错事件
        hls.on(Hls.Events.ERROR, function (event, data) {
			
	        /**
	        console.log('直播源无效，请更换直播源');
	        art.loading.show = false;
	        art.notice.show = '此直播源无效，将更换直播源';
	        setTimeout(() => {
		        art.switchQuality('http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221225728/index.m3u8');
		    }, 5000);
		    */
		    
		    if (data.fatal) {  
		        switch(data.type) {
		        case Hls.ErrorTypes.NETWORK_ERROR:
		          /** 
		          if (data.details === Hls.ErrorDetails.MANIFEST_LOAD_ERROR || data.details === Hls.ErrorDetails.MANIFEST_LOAD_TIMEOUT || data.details === Hls.ErrorDetails.MANIFEST_PARSING_ERROR) {
		            hls.loadSource('');
		          }else {
		            hls.startLoad();
		          }
		          */
		          var channel = $('select.chosen-select').val();
		          console.error('网络相关的错误');
		          
		          // 上报错误
		          sourceErrorUpdate(channel, url);
		              
		          art.loading.show = false;
	        	  art.notice.show = '此直播源无效，请更换直播源';
		          break;
		        case Hls.ErrorTypes.MEDIA_ERROR:
		          console.error('媒体/视频相关错误');    
		          hls.recoverMediaError();
		          break;
		        default:
		          console.error('其他错误');
		          hls.destroy();
		          break;
		        }
		    } 		        
	    });
    } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
        video.src = url;
    } else {
        art.notice.show = 'Unsupported playback format: m3u8';
    }
}

/** 播放器可以播放事件 */
art.once('video:canplay', () => {
    console.info('video:canplay');
});

/** 直播源加载错误时 
art.on('error', (error, reconnectTime) => {
    console.log('直播源无效，请更换直播源');
    
});
**/

/** 动态设置画质列表 **/
function addQuality(sourceList){
	
	let nameList = ['源Ⅰ','源Ⅱ','源Ⅲ','源Ⅳ','源Ⅴ','源Ⅵ','源Ⅶ','源Ⅷ','源Ⅸ','源Ⅹ']
	let qualityList = []
	
	sourceList.forEach(function(val, index, arr){
		
		var isDefault = index == 0;
		var name = "源";
		if(index < nameList.length){
			name = nameList[index];
		} else {
			name = name + (index + 1);
		}		
		var quality = {'default':isDefault,'html':name,'url':val.url};
		qualityList.push(quality);
	});
	
	// 动态
	art.quality = qualityList;
}


/** 动态设置画质列表 **/
function addTempQuality(link){
	
	let qualityList = []

	var name = '临时源';
	var quality = {'default':true,'html':name,'url':link};
	qualityList.push(quality);

	// 动态
	art.quality = qualityList;
}


/** 直播源错误上报 **/
function sourceErrorUpdate(channel, url){
	
var errorUpdate={
  "channel": channel,
  "url": url
}	

$.ajax({
    type:"POST",
    url:"/live/error/update",
    contentType: "application/json", //必须这样写
    dataType:"json",
    data:JSON.stringify(errorUpdate),//schoolList是你要提交是json字符串
    success:function (data) {
	    console.log('直播源错误上报成功');
    },
    error: function(err){
	 	console.error(err);
	}
});
	
}


</script>
</html>